package com.taa.domain.trade.service;

import com.taa.domain.trade.adapter.repository.ITradeRepository;
import com.taa.domain.trade.model.entity.OrderEntity;
import com.taa.domain.trade.model.entity.ProductEntity;
import com.taa.domain.trade.service.chain.factory.DefaultChainFactory;
import com.taa.domain.trade.service.discount.IDiscountStrategy;
import com.taa.types.enums.ResponseCode;
import com.taa.types.exception.AppException;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author: taa
 * @Desc: 订单处理模板类
 * @Create: 2025-06-02 13:54
 **/
@Slf4j
public abstract class AbstractOrderService implements IOrderService, IPriceCalculationService {

    protected ITradeRepository repository;

    protected final DefaultChainFactory defaultChainFactory;

    protected final Map<String, IDiscountStrategy> discountStrategyGroup;

    public AbstractOrderService(ITradeRepository repository, DefaultChainFactory defaultChainFactory, Map<String, IDiscountStrategy> discountStrategyGroup) {
        this.repository = repository;
        this.defaultChainFactory = defaultChainFactory;
        this.discountStrategyGroup = discountStrategyGroup;
    }

    @Override
    public OrderEntity createOrder(String userName, List<ProductEntity> productEntityList) {
        if (userName == null || productEntityList == null || productEntityList.isEmpty()) {
            throw new AppException(ResponseCode.ILLEGAL_PARAMETER.getCode(), ResponseCode.ILLEGAL_PARAMETER.getInfo());
        }
        // 1. 获取商品ID列表
        List<Long> productIdList = new ArrayList<>();
        for (ProductEntity productEntity : productEntityList) {
            productIdList.add(productEntity.getProductId());
        }
        // 2. 责任链校验
        if (!validate(userName, productIdList)) {
            throw new RuntimeException("订单校验失败");
        }

        // 2. 获取并应用折扣策略, 计算总价
        repository.fillProductStrategy(productEntityList);
        BigDecimal totalDiscountPrice = BigDecimal.ZERO;
        BigDecimal totalOriginalPrice = BigDecimal.ZERO;
        
        for (ProductEntity productEntity : productEntityList) {
            BigDecimal discountPrice = applyDiscount(productEntity);
            productEntity.setDiscountPrice(discountPrice);
            totalOriginalPrice = totalOriginalPrice.add(productEntity.getOriginalPrice());
            totalDiscountPrice = totalDiscountPrice.add(discountPrice);
        }

        // 3. 扣减库存
        boolean status = reduceStock(productIdList);

        if (!status) {
            throw new RuntimeException("库存不足");
        }

        // 4. 生成订单
        return generateOrder(userName, productEntityList, totalOriginalPrice, totalDiscountPrice);
    }

    public abstract boolean validate(String userName, List<Long> productIdList);

    public abstract boolean reduceStock(List<Long> productIdList);

    public abstract OrderEntity generateOrder(String userName, List<ProductEntity> productEntityList,  BigDecimal totalOriginalPrice ,BigDecimal totalDiscountPrice);

}

